/*
 * Copyright (c) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef NWEB_DELEGATE_H
#define NWEB_DELEGATE_H

#include <condition_variable>
#include <string>
#include "cef/include/cef_command_line.h"
#include "nweb_application.h"
#include "nweb_delegate_interface.h"
#include "nweb_display_listener.h"
#include "nweb_event_handler.h"
#include "nweb_handler_delegate.h"
#include "nweb_inputmethod_client.h"
#include "nweb_render_handler.h"
#include "ohos_adapter_helper.h"

namespace OHOS::NWeb {
class NWebDelegate : public NWebDelegateInterface,
                        public virtual CefRefCount {
 public:
  NWebDelegate(int argc, const char* argv[]);
  ~NWebDelegate();
  bool Init(void* window);

  bool IsReady() override;
  void OnDestroy(bool is_close_all) override;

  void RegisterDownLoadListener(
      std::shared_ptr<NWebDownloadCallback> downloadListener) override;
  void RegisterNWebHandler(std::shared_ptr<NWebHandler> handler) override;
  void RegisterRenderCb(
      std::function<void(const char*)> render_update_cb) override;

  void SetInputMethodClient(
      CefRefPtr<NWebInputMethodClient> client) override;

  void Resize(uint32_t width, uint32_t height) override;
  void OnTouchPress(int32_t id, double x, double y) override;
  void OnTouchRelease(int32_t id, double x, double y) override;
  void OnTouchMove(int32_t id, double x, double y) override;
  void OnTouchCancel() override;
  bool SendKeyEvent(int32_t keyCode, int32_t keyAction) override;
  void SendMouseWheelEvent(double x, double y, double deltaX, double deltaY) override;
  void SendMouseEvent(int x, int y, int button, int action) override;
  void NotifyScreenInfoChanged(RotationType rotation,
                               OrientationType orientation) override;

  void Load(const std::string& url) override;
  bool IsNavigatebackwardAllowed() const override;
  bool IsNavigateForwardAllowed() const override;
  bool CanNavigateBackOrForward(int num_steps) const override;
  void NavigateBack() const override;
  void NavigateForward() const override;
  void NavigateBackOrForward(int32_t step) const override;
  void DeleteNavigateHistory() override;
  void Reload() const override;
  void ReloadOriginalUrl() const override;
  void Zoom(float zoomFactor) const override;
  bool ZoomIn() const override;
  bool ZoomOut() const override;
  void Stop() const override;
  void ExecuteJavaScript(const std::string& code) const override;
  void ExecuteJavaScript(
      const std::string& code,
      std::shared_ptr<NWebValueCallback<std::string>> callback) const override;
  void PutBackgroundColor(int color) const override;
  void InitialScale(float scale) const override;
  void OnPause() override;
  void OnContinue() override;
  std::shared_ptr<NWebPreference> GetPreference() const override;
  std::string Title() override;
  HitTestResult GetHitTestResult() const override;
  int PageLoadProgress() override;
  float Scale() override;
  void Load(std::string& url,
            std::map<std::string, std::string> additionalHttpHeaders) override;
  void LoadWithDataAndBaseUrl(const std::string& baseUrl,
                              const std::string& data,
                              const std::string& mimeType,
                              const std::string& encoding,
                              const std::string& historyUrl) override;
  void LoadWithData(const std::string& data,
                    const std::string& mimeType,
                    const std::string& encoding) override;
  int ContentHeight() override;
  void RegisterArkJSfunction(
      const std::string& object_name,
      const std::vector<std::string>& method_list) const override;

  void UnregisterArkJSfunction(
      const std::string& object_name,
      const std::vector<std::string>& method_list) const override;

  void RegisterNWebJavaScriptCallBack(
      std::shared_ptr<NWebJavaScriptResultCallBack> callback) override;
  void OnFocus() const override;
  void OnBlur() const override;
  bool SetZoomInFactor(float factor);
  bool SetZoomOutFactor(float factor);
 public:
  int argc_;
  const char** argv_;

 private:
  void RunMessageLoop();
  void InitializeCef(std::string url, void* window);
  const CefRefPtr<CefBrowser> GetBrowser() const;
  void RequestVisitedHistory();

 private:
  float zoom_in_factor_ = 2.0;
  float zoom_out_factor_ = -2.0;
  float intial_scale_ = 0;
  bool has_requested_visited_history = false;
  CefRefPtr<NWebApplication> nweb_app_ = nullptr;
  CefRefPtr<NWebHandlerDelegate> handler_delegate_ = nullptr;
  CefRefPtr<NWebRenderHandler> render_handler_ = nullptr;
  std::shared_ptr<NWebEventHandler> event_handler_ = nullptr;
  std::shared_ptr<NWebPreferenceDelegate> preference_delegate_ = nullptr;
  std::unique_ptr<OHOS::NWeb::DisplayManagerAdapter>
    display_manager_adapter_ = nullptr;
  std::shared_ptr<OHOS::NWeb::DisplayScreenListener>
    display_listener_ = nullptr;
  // Members only accessed on the main thread.
  bool hidden_ = false;
};
}  // namespace OHOS::NWeb
#endif
